package com.company.堆栈队列;

import java.util.Scanner;
import java.util.Stack;

/**
 * **
 *
 * @param
 * @author jianjian.zhang
 * @date 2022/07/17 20:03
 * @return
 * @description:计算器的实现 * 栈实现完成计算一个表达式的结果
 * * 思路：
 * * 我们需要两个栈来辅助实现
 *    符号栈（用来存储符号）
 *    数字栈（用来存储运算的数字和结果）
 * *1.通过一个index值(索引)，来遍历我们的表达式
 * * 2.如果我们发现是一个数字。就直接如数栈
 * * 3.如果发现扫描到的是一个符号,就分如下情况
 * * 3.1 如果发现当前的符号栈为空，就直接入栈。
 * * 3.2 如果符号栈有操作符，就进行比较。
 * * 1）如果当前的操作符的优先级小于或者等于栈中的操作符，这时就需要从数栈中pop出两个数
 * * 然后再从符号栈中pop出一个符号，进行运算。将得到的结果，入数栈。然后将当前的操作符入符号栈。
 * * 2）如果当前的操作符的优先级大于栈中的操作符，就直接入符号栈
 * * 4.当表达式扫描完毕，就顺序的从数栈和符号栈中pop出相应的数和符号，并运行
 * * 5.最后在数栈只有一个数字，就是表达式的结果。
 */


public class 计算器的实现 {


    public static void main(String[] args) {
        Stack<Integer> numStack = new Stack<>();
        Stack<Character> strStack = new Stack<>();

        int num1 = 0;
        int num2 = 0;
        char oper;
        int result = 0;
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (isNumber(chars[i])) {
                // 判断为数字入数字栈
                numStack.push(Integer.parseInt(String.valueOf(chars[i])));
            } else {
                if (strStack.isEmpty()) {
                    strStack.push(chars[i]);
                } else {
                    if (priority(chars[i]) <= priority(strStack.get(strStack.toArray().length - 1))) {
                        num1 = Integer.parseInt(String.valueOf(numStack.pop()));
                        num2 = Integer.parseInt(String.valueOf(numStack.pop()));
                        oper = strStack.pop();
                        result = cel(num1, num2, oper);
                        numStack.push(result);
                        strStack.push(chars[i]);
                    } else {
                        strStack.push(chars[i]);
                    }
                }
            }
        }

        //表达式遍历完毕后，则按顺序从数栈和符号栈中pop出值进行运算
        while (!numStack.isEmpty() && !strStack.isEmpty()) {
            if (str.isEmpty()) {
                break;
            }
            num1 = Integer.parseInt(String.valueOf(numStack.pop()));
            num2 = Integer.parseInt(String.valueOf(numStack.pop()));
            oper = strStack.pop();
            result = cel(num1, num2, oper);
            numStack.push(result);

        }
        System.out.println(result);

    }

    /**
     * 计算
     *
     * @param num1
     * @param num2
     * @param oper
     * @return
     */
    public static int cel(int num1, int num2, char oper) {
        //存放结果
        int result = 0;
        switch (oper) {
            case '*':
                result = num1 * num2;
                break;
            case '/':
                result = num1 / num2;
                break;
            case '+':
                result = num1 + num2;
                break;
            case '-':
                result = num2 - num1;
                break;
            default:
                break;
        }
        return result;
    }

    /**
     * 判断优先级
     *
     * @param oper
     * @return
     */

    public static int priority(char oper) {
        if (oper == '*' || oper == '/') {
            return 1;
        } else {
            return 0;
        }
    }

    /**
     * 判断是否为数字或者字符
     *
     * @param c
     * @return
     */

    private static boolean isNumber(char c) {
        if (c == '*' || c == '/' || c == '-' || c == '+') {
            return false;
        } else {
            return true;
        }
    }


}
